package com.example.securitydemo.configuration.security;

import com.auth0.jwt.exceptions.JWTVerificationException;
import com.example.securitydemo.model.pojo.TokenUser;
import com.example.securitydemo.utils.JwtUtils;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * 这个过滤器是在每次认证的时候就会调用。登录的时候是两个过程，先走登录过滤器，再走认证过滤器
 */
public class TokenAuthenticationFilter extends BasicAuthenticationFilter {

    public TokenAuthenticationFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        // 每次需要登录验证的时候就验证是否有token就ok了
        try {
            String token = request.getHeader("token");
            if(token == null){
                chain.doFilter(request,response);
                return;
            }
            // 解析成功，说明Token有效
            TokenUser tokenUser = JwtUtils.parseUserToken(token);
            List<String> authorities = tokenUser.getAuthorities();
            // 每次解析完都要把security的token放到securityContext中。这个是security拿来做权限的凭证
            Authentication authToken = new UsernamePasswordAuthenticationToken(tokenUser.getUsername(),token, AuthorityUtils.createAuthorityList(authorities.toArray(new String[authorities.size()])));
            SecurityContextHolder.getContext().setAuthentication(authToken);// 这个一定要加上，不然没有凭证。security只认这个凭证
            // 解析成功，放行
            System.out.println("666");
            System.out.println("别打脸");
        } catch (JWTVerificationException e) {
            SecurityContextHolder.clearContext();
            e.printStackTrace();
        }

        chain.doFilter(request,response);
    }

}
